//! 计数工具

/// 找到下一个 index
pub trait CycleCounter {
    /// 初始化最大数，然后找到下一个 index，抵达最大值后重新从 0 开始
    ///
    /// 例如，设置 max_count = 5，则 N -> 2 -> 3 -> 4 -> 0
    fn next(&self, cycle_count: Self) -> Self;
}

macro_rules! cycle_counter_impl {
    ($t:ty) => {
        impl CycleCounter for $t {
            fn next(&self, cycle_count: Self) -> Self {
                let next = *self + 1;
                if next >= cycle_count {
                    next % cycle_count
                } else {
                    next
                }
            }
        }
    };

    ($($t:ty),+ $(,)?) => {
        $(cycle_counter_impl!($t);)+
    };
}

cycle_counter_impl![usize, isize, i32];

#[cfg(test)]
mod test {

    use super::*;

    #[test]
    fn test_next_index() {
        let max = 3;

        assert_eq!(1, 0.next(max));
        assert_eq!(2, 1.next(max));
        assert_eq!(2, 4.next(max));
        assert_eq!(0, 5.next(max));
    }
}
